﻿using ArtMath.Core.Data;
using ArtMath.Data.Converter;
using ArtMath.CommonType;
using ArtMath.Resource;
using System;
using System.ComponentModel;
using System.Drawing;

namespace ArtMath.Data
{
    [Serializable, TypeConverter(typeof(SizeSConverter))]
    public class SizeS : IStringSettable, IFormatPainter<SizeS>
    {
        PadStringX width, height;
        public event Action<SizeD, SizeD> SizeChanged;
        public SizeS(SketchPad pad, string width = null, string height = null)
        {
            Width = new PadStringX(pad, width);
            Height = new PadStringX(pad, height);
        }
        public PadStringX Width
        {
            get { return width; }
            set
            {
                if (width is object)
                {
                    width.ParametersValueChanged -= WH_ParametersValueChanged;
                    width.ExpressionSet -= WH_ExpressionSet;
                }
                width = value;
                if (width is object)
                {
                    width.ParametersValueChanged += WH_ParametersValueChanged;
                    width.ExpressionSet += WH_ExpressionSet;
                }
            }
        }
        public PadStringX Height
        {
            get { return height; }
            set
            {
                if (height is object)
                {
                    height.ParametersValueChanged -= WH_ParametersValueChanged;
                    height.ExpressionSet -= WH_ExpressionSet;
                }
                height = value;
                if (height is object)
                {
                    height.ParametersValueChanged += WH_ParametersValueChanged;
                    height.ExpressionSet += WH_ExpressionSet;
                }
            }
        }
        void WH_ParametersValueChanged(DocStringX sender, ParametersValueChangedEventArgs e)
        {
            whEvent(sender, e.OldValue);
        }
        void WH_ExpressionSet(StringX sender, ExpressionSetEventArgs e)
        {
            whEvent(sender, e.OldValue);
        }
        void whEvent(StringX sender, double oldValue)
        {
            if (ReferenceEquals(sender, Width))
            {
                SizeChanged?.Invoke(new SizeD(oldValue, Height.Value), new SizeD(sender.Value, Height.Value));
            }
            else
            {
                SizeChanged?.Invoke(new SizeD(Width.Value, oldValue), new SizeD(Width.Value, sender.Value));
            }
        }
        public void SetFromSizeD(double width, double height)
        {
            Width.SetExpression(width);
            Height.SetExpression(height);
        }
        public void SetFromSizeD(SizeD size)
        {
            SetFromSizeD(size.Width, size.Height);
        }
        public void SetFromString(string exp)
        {
            string[] tokens = exp.Split(',', '，');
            if (tokens.Length == 2)
            {
                Width.SetExpression(tokens[0].Trim());
                Height.SetExpression(tokens[1].Trim());
            }
            else
            {
                throw new ArgumentException(string.Format(Resources.Translate("AcceptNArgs"), Resources.Translate("Size"), 2));
            }
        }
        public SizeF ToSizeF()
        {
            return new SizeF(Width.FloatValue, Height.FloatValue);
        }
        public SizeD ToSizeD()
        {
            return new SizeD(Width.Value, Height.Value);
        }
        public override string ToString()
        {
            return Width.ToString() + ", " + Height.ToString();
        }

        public void UseFormat(SizeS obj = null)
        {
            Width.UseFormat(obj.Width);
            Height.UseFormat(obj.Height);
        }
    }
}
